package start.spring.basic.demo.controller.demo;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import start.spring.basic.demo.common.DemoConstant;
import start.spring.basic.demo.controller.BaseController;
import start.spring.basic.log.ServiceLog;
import start.spring.basic.response.ResponseData;
import start.spring.basic.util.common.MfaAuthenticator;
import start.spring.basic.util.common.QRCodeUtil;

/**
 * 
 * ****************************************************************************
 * 基于虚拟mfa authenticator（如google authenticator）的绑定及验证入口
 *
 * @author(作者)：xuyongyun	
 * @date(创建日期)：2023年4月1日
 ******************************************************************************
 */
@Slf4j
@RestController
@RequestMapping("/mfa")
@Api(tags = "虚拟mfa authenticator相关接口")
public class MfaAuthController extends BaseController {
	
	@ServiceLog(businessType = "获取绑定用的二维码", systemType = DemoConstant.SYSTEM_TYPE, recordResult = false, userId = "")
	@RequestMapping(value = "/get/bindimage", method = {RequestMethod.GET})
	@ResponseBody
	@ApiOperation(value = "获取绑定用的二维码", notes = "")
	public void getBindImage(HttpServletRequest request,HttpServletResponse response) throws IOException {
		String userId = "testuser";//实际开发时需要根据系统权限框架获取登录用户id
		String secret = MfaAuthenticator.genSecret(userId);
		//实际开发中密钥需要保存在数据库，当前demo为了测试方便输出到控制台
		log.info("secret is: {}", secret);
        String qrCodeContent = MfaAuthenticator.getQrcodeUrl(userId, secret);
        log.info("qrCodeContent is: {}", qrCodeContent);
        QRCodeUtil.createQrcode(qrCodeContent, response.getOutputStream());
	}
	
	@ServiceLog(businessType = "校验动态码是否正确", systemType = DemoConstant.SYSTEM_TYPE, recordResult = true, userId = "")
	@RequestMapping(value = "/valid/code", method = {RequestMethod.GET})
	@ResponseBody
	@ApiOperation(value = "校验动态码是否正确", notes = "")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "code", value = "动态码", dataType = "long", required = true),
		@ApiImplicitParam(name = "secret", value = "密钥", dataType = "String", required = true)
	})
	public ResponseData<String> getBindImage(long code, String secret) throws IOException {
		//TODO 注意实际开发secret正常需要在服务端获取，不允许通过网络传递
		//此demo由于服务端未存储验证码，因此从页面传递，仅用于验证工具类是否可用
		boolean codeValid = MfaAuthenticator.checkCode(secret, code, 1);
		
		if(codeValid) {
			return ResponseData.successMsg("校验通过！");
		}else {
			return ResponseData.successMsg("动态码错误！");
		}
	}
	
}
